#include <MQ_Virtual_Engine/BindInfo.hpp>
#include <cassert>

#include <gtest/gtest.h>
// void testBindInfoManager()
// {
//     // 定义数据库文件路径
//     const std::string dbPath = "./test_bindinfo.db";

//     // 删除之前的数据库文件，确保测试干净
//     std::filesystem::remove(dbPath);

//     // 创建 BindInfoManager 实例
//     MY_MQ::BindInfoManager bindInfoManager(dbPath);

//     // 测试绑定操作：单个交换机绑定一个队列
//     assert(bindInfoManager.Bind("exchange1", "queue1", "bindingKey1", true) == true);
//     assert(bindInfoManager.exist("exchange1", "queue1") == true);

//     // 测试绑定操作：单个交换机绑定多个队列
//     assert(bindInfoManager.Bind("exchange1", "queue2", "bindingKey2", true) == true);
//     assert(bindInfoManager.exist("exchange1", "queue2") == true);

//     // 测试绑定操作：另一个交换机绑定队列
//     assert(bindInfoManager.Bind("exchange2", "queue3", "bindingKey3", true) == true);
//     assert(bindInfoManager.exist("exchange2", "queue3") == true);

//     // 测试 GetQueueBindingMap：获取 exchange1 绑定的队列
//     auto exchange1Bindings = bindInfoManager.GetQueueBindingMap("exchange1");
//     assert(exchange1Bindings.size() == 2);
//     assert(exchange1Bindings.find("queue1") != exchange1Bindings.end());
//     assert(exchange1Bindings.find("queue2") != exchange1Bindings.end());

//     // 测试 GetQueueBindingMap：获取 exchange2 绑定的队列
//     auto exchange2Bindings = bindInfoManager.GetQueueBindingMap("exchange2");
//     assert(exchange2Bindings.size() == 1);
//     assert(exchange2Bindings.find("queue3") != exchange2Bindings.end());

//     // 测试移除队列绑定
//     assert(bindInfoManager.Unbind("exchange1", "queue1") == true);
//     assert(bindInfoManager.exist("exchange1", "queue1") == false);

//     // 测试移除交换机所有绑定
//     bindInfoManager.RemoveExchangeBindings("exchange1");
//     exchange1Bindings = bindInfoManager.GetQueueBindingMap("exchange1");
//     assert(exchange1Bindings.size() == 0);

//     // 测试移除队列所有绑定
//     bindInfoManager.RemoveQueueBindings("queue3");
//     exchange2Bindings = bindInfoManager.GetQueueBindingMap("exchange2");
//     assert(exchange2Bindings.size() == 0);

//     // 测试数据库恢复
//     bindInfoManager.Bind("exchange3", "queue4", "bindingKey4", true);
//     bindInfoManager.Bind("exchange3", "queue5", "bindingKey5", true);

//     MY_MQ::BindInfoManager newBindInfoManager(dbPath); // 使用同一数据库路径创建新实例
//     auto exchange3Bindings = newBindInfoManager.GetQueueBindingMap("exchange3");
//     assert(exchange3Bindings.size() == 2);
//     assert(exchange3Bindings.find("queue4") != exchange3Bindings.end());
//     assert(exchange3Bindings.find("queue5") != exchange3Bindings.end());

//     // 测试清除临时绑定
//     bindInfoManager.Bind("exchange4", "queue6", "bindingKey6", false);
//     bindInfoManager.clearTmp();
//     assert(bindInfoManager.exist("exchange4", "queue6") == false);

//     std::cout << "All tests passed successfully!" << std::endl;
// }


// 测试前的环境准备
// 测试前的环境准备
class BindInfoManagerTest : public ::testing::Test {
protected:
    std::string db_file = "./test_bindinfo.db";
    MY_MQ::BindInfoManager manager{db_file};

    void SetUp() override {
        // 初始化时，确保数据库是空的
        manager.clearTmp(); // 使用 clearTmp 代替 clear
    }

    void TearDown() override {
        // 测试结束后删除数据库文件
        std::filesystem::remove(db_file);
    }
};

// 测试绑定关系的添加和查询
TEST_F(BindInfoManagerTest, TestBindAndExist) {
    std::string exchange = "test_exchange";
    std::string queue = "test_queue";
    std::string bindingKey = "key";
    
    // 绑定一个队列到交换机
    EXPECT_TRUE(manager.Bind(exchange, queue, bindingKey, true));

    // 检查绑定关系是否存在
    EXPECT_TRUE(manager.exist(exchange, queue));

    // 获取绑定信息并验证其内容
    auto bindInfo = manager.GetBindInfo(exchange, queue);
    ASSERT_NE(bindInfo, nullptr);
    EXPECT_EQ(bindInfo->_ExchangeName, exchange);
    EXPECT_EQ(bindInfo->_Queue_Name, queue);
    EXPECT_EQ(bindInfo->_BindingKey, bindingKey);
    EXPECT_TRUE(bindInfo->_durable);
}

// 测试解绑操作
TEST_F(BindInfoManagerTest, TestUnbind) {
    std::string exchange = "test_exchange";
    std::string queue = "test_queue";
    std::string bindingKey = "key";

    // 绑定并检查绑定关系
    EXPECT_TRUE(manager.Bind(exchange, queue, bindingKey, true));
    EXPECT_TRUE(manager.exist(exchange, queue));

    // 解绑并验证绑定关系是否已被移除
    EXPECT_TRUE(manager.Unbind(exchange, queue));
    EXPECT_FALSE(manager.exist(exchange, queue));
}

// 测试删除交换机绑定
TEST_F(BindInfoManagerTest, TestRemoveExchangeBindings) {
    std::string exchange = "test_exchange";
    std::string queue1 = "queue1";
    std::string queue2 = "queue2";

    // 绑定两个队列到同一个交换机
    EXPECT_TRUE(manager.Bind(exchange, queue1, "key1", true));
    EXPECT_TRUE(manager.Bind(exchange, queue2, "key2", true));

    // 删除交换机的所有绑定
    manager.RemoveExchangeBindings(exchange);

    // 验证所有队列都被解绑
    EXPECT_FALSE(manager.exist(exchange, queue1));
    EXPECT_FALSE(manager.exist(exchange, queue2));
}

// 测试删除队列绑定
TEST_F(BindInfoManagerTest, TestRemoveQueueBindings) {
    std::string exchange1 = "exchange1";
    std::string exchange2 = "exchange2";
    std::string queue = "test_queue";

    // 将同一个队列绑定到不同的交换机
    EXPECT_TRUE(manager.Bind(exchange1, queue, "key1", true));
    EXPECT_TRUE(manager.Bind(exchange2, queue, "key2", true));

    // 删除该队列的所有绑定
    manager.RemoveQueueBindings(queue);

    // 验证队列是否从所有交换机中解绑
    EXPECT_FALSE(manager.exist(exchange1, queue));
    EXPECT_FALSE(manager.exist(exchange2, queue));
}

// 测试从数据库恢复绑定关系
TEST_F(BindInfoManagerTest, TestRecovery) {
    std::string exchange = "test_exchange";
    std::string queue = "test_queue";
    std::string bindingKey = "key";

    // 绑定一个队列到交换机
    EXPECT_TRUE(manager.Bind(exchange, queue, bindingKey, true));

    // 重新创建一个BindInfoManager来测试恢复
    MY_MQ::BindInfoManager newManager(db_file);

    // 验证绑定关系是否正确恢复
    EXPECT_TRUE(newManager.exist(exchange, queue));
    auto bindInfo = newManager.GetBindInfo(exchange, queue);
    ASSERT_NE(bindInfo, nullptr);
    EXPECT_EQ(bindInfo->_ExchangeName, exchange);
    EXPECT_EQ(bindInfo->_Queue_Name, queue);
    EXPECT_EQ(bindInfo->_BindingKey, bindingKey);

    EXPECT_TRUE(bindInfo->_durable);
}

// 测试临时绑定的清理
TEST_F(BindInfoManagerTest, TestClearTmp) {
    std::string exchange1 = "exchange1";
    std::string exchange2 = "exchange2";
    std::string queue = "test_queue";

    // 绑定一个持久化的队列和一个非持久化的队列
    EXPECT_TRUE(manager.Bind(exchange1, queue, "key1", true));
    EXPECT_TRUE(manager.Bind(exchange2, queue, "key2", false));

    // 清理临时绑定
    manager.clearTmp();

    // 持久化队列的绑定应当保留，非持久化的应当删除
    //但是持久化知识存储在数据库中，后面再找救找不到了
    EXPECT_FALSE(manager.exist(exchange1, queue));
    EXPECT_FALSE(manager.exist(exchange2, queue));
}


int main(int argc, char **argv)
{
    fmtlog::setHeaderPattern("{s} \t| {t} \t| {l} \t| {YmdHMS} \t| {g} \t| \n\t:");
    fmtlog::startPollingThread(12); 

    // testBindInfoManager();
    //启用 google test
    ::testing::InitGoogleTest(&argc, argv); 
    return RUN_ALL_TESTS();
}